<template><div><h2 id="线程协作与性能提升" tabindex="-1"><a class="header-anchor" href="#线程协作与性能提升"><span>线程协作与性能提升</span></a></h2>
<p>问题制造线程：用单线程的方式不断绘制320 * 320 的BMP灰度图片，像素仅有FF和00（黑和白两种），要求白底颜色图片上制造随机数量黑点，不断写入到文件夹中（为保护你的硬盘，找个破U盘写到U盘里，并限定生成文件的数量上限为）
问题解决线程组：监听U盘的文件目录，一旦有新的图片产生，马上读取文件，并计算黑点围成的多边形面积，计算出结果后马上删除图片</p>
<p>要求：在完成程序的基础上，追求文件写入完成与全部删除完成的时间差尽可能小
进阶要求：（可能会报废U盘）不限定生成图片数量上限，文件夹内同时存在的图片数量不得多于2张，（想想这不就是高并发的幂等要求吗）</p>
<div class="language-java line-numbers-mode has-collapsed-lines collapsed" data-highlighter="shiki" data-ext="java" style="--vp-collapsed-lines:15;background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#7F848E;font-style:italic">/**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @Author haomingze</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @Date 2025/5/9 17:17</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @description:</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> */</span></span>
<span class="line"><span style="color:#C678DD">public</span><span style="color:#C678DD"> class</span><span style="color:#E5C07B"> BmpGenerator</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> static</span><span style="color:#C678DD"> final</span><span style="color:#C678DD"> int</span><span style="color:#E06C75"> IMAGE_SIZE </span><span style="color:#56B6C2">=</span><span style="color:#D19A66"> 320</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> static</span><span style="color:#C678DD"> final</span><span style="color:#C678DD"> int</span><span style="color:#E06C75"> MAX_BLACK_DOTS </span><span style="color:#56B6C2">=</span><span style="color:#D19A66"> 1000</span><span style="color:#ABB2BF">;</span><span style="color:#7F848E;font-style:italic"> // 随机黑点数</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> static</span><span style="color:#C678DD"> final</span><span style="color:#E5C07B"> File</span><span style="color:#E06C75"> outputDir </span><span style="color:#56B6C2">=</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> File</span><span style="color:#E06C75">(</span><span style="color:#98C379">"D:/"</span><span style="color:#E06C75">)</span><span style="color:#ABB2BF">;</span><span style="color:#7F848E;font-style:italic"> // 输出目录</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> static</span><span style="color:#C678DD"> final</span><span style="color:#E5C07B"> Random</span><span style="color:#E06C75"> random </span><span style="color:#56B6C2">=</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> Random</span><span style="color:#E06C75">()</span><span style="color:#ABB2BF">;</span><span style="color:#7F848E;font-style:italic"> // 随机数</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> static</span><span style="color:#C678DD"> final</span><span style="color:#C678DD"> int</span><span style="color:#E06C75"> FILE_LIMIT </span><span style="color:#56B6C2">=</span><span style="color:#D19A66"> 1000</span><span style="color:#ABB2BF">;</span><span style="color:#7F848E;font-style:italic"> // 最大生成数量</span></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> static</span><span style="color:#E5C07B"> HashMap</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E5C07B">String</span><span style="color:#ABB2BF">,</span><span style="color:#E5C07B">Object</span><span style="color:#ABB2BF">></span><span style="color:#E06C75"> lockMap </span><span style="color:#56B6C2">=</span><span style="color:#C678DD"> new</span><span style="color:#E5C07B"> HashMap</span><span style="color:#ABB2BF">&#x3C;></span><span style="color:#E06C75">()</span><span style="color:#ABB2BF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> startGenerating</span><span style="color:#ABB2BF">()</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#C678DD">        int</span><span style="color:#E06C75"> fileCount</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">        while</span><span style="color:#ABB2BF"> (fileCount </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> FILE_LIMIT) {</span></span>
<span class="line"><span style="color:#C678DD">            try</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">                File</span><span style="color:#E06C75"> outputFile</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> File</span><span style="color:#ABB2BF">(outputDir, </span><span style="color:#98C379">"image_"</span><span style="color:#56B6C2"> +</span><span style="color:#E5C07B"> System</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">currentTimeMillis</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">+</span><span style="color:#98C379"> ".bmp"</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#61AFEF">                generateBmp</span><span style="color:#ABB2BF">(outputFile);</span></span>
<span class="line"><span style="color:#ABB2BF">                fileCount++;</span></span>
<span class="line"><span style="color:#E5C07B">                Thread</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">sleep</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">50</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 避免生成过快</span></span>
<span class="line"><span style="color:#ABB2BF">            } </span><span style="color:#C678DD">catch</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">InterruptedException</span><span style="color:#E06C75;font-style:italic"> e</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"><span style="color:#E5C07B">                e</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">printStackTrace</span><span style="color:#ABB2BF">();</span></span>
<span class="line"><span style="color:#ABB2BF">            }</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> generateBmp</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">File</span><span style="color:#E06C75;font-style:italic"> file</span><span style="color:#ABB2BF">)</span><span style="color:#ABB2BF">  {</span></span>
<span class="line"><span style="color:#E5C07B">        Object</span><span style="color:#E06C75"> lock</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> Object</span><span style="color:#ABB2BF">();</span></span>
<span class="line"><span style="color:#E5C07B">        lockMap</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">put</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getAbsolutePath</span><span style="color:#ABB2BF">(),lock);</span></span>
<span class="line"><span style="color:#C678DD">        synchronized</span><span style="color:#ABB2BF"> (lock){</span></span>
<span class="line"><span style="color:#C678DD">            try</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75"> fos</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> FileOutputStream</span><span style="color:#ABB2BF">(file)) {</span></span>
<span class="line"><span style="color:#61AFEF">                writeFileHeader</span><span style="color:#ABB2BF">(fos); </span><span style="color:#7F848E;font-style:italic">// BMP文件头 (14字节)</span></span>
<span class="line"><span style="color:#61AFEF">                writeInfoHeader</span><span style="color:#ABB2BF">(fos); </span><span style="color:#7F848E;font-style:italic">// BMP信息头 (40字节)</span></span>
<span class="line"><span style="color:#61AFEF">                writePixelData</span><span style="color:#ABB2BF">(fos); </span><span style="color:#7F848E;font-style:italic">// 像素数据</span></span>
<span class="line"><span style="color:#ABB2BF">            } </span><span style="color:#C678DD">catch</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">IOException</span><span style="color:#E06C75;font-style:italic"> e</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"><span style="color:#C678DD">                throw</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> RuntimeException</span><span style="color:#ABB2BF">(e);</span></span>
<span class="line"><span style="color:#ABB2BF">            }</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 写入文件头</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> fos</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@throws</span><span style="color:#E5C07B;font-style:italic"> IOException</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> writeFileHeader</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75;font-style:italic"> fos</span><span style="color:#ABB2BF">)</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">0x42</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 'B'</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">0x4D</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 'M'</span></span>
<span class="line"><span style="color:#C678DD">        int</span><span style="color:#E06C75"> fileSize</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 14</span><span style="color:#56B6C2"> +</span><span style="color:#D19A66"> 40</span><span style="color:#56B6C2"> +</span><span style="color:#ABB2BF"> IMAGE_SIZE </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> IMAGE_SIZE;</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, fileSize);</span></span>
<span class="line"><span style="color:#61AFEF">        writeShortLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 保留</span></span>
<span class="line"><span style="color:#61AFEF">        writeShortLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 保留</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">14</span><span style="color:#56B6C2"> +</span><span style="color:#D19A66"> 40</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 像素数据偏移</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 写入信息头</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> fos</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@throws</span><span style="color:#E5C07B;font-style:italic"> IOException</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> writeInfoHeader</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75;font-style:italic"> fos</span><span style="color:#ABB2BF">)</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">40</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 信息头大小</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, IMAGE_SIZE); </span><span style="color:#7F848E;font-style:italic">// 宽度</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, IMAGE_SIZE); </span><span style="color:#7F848E;font-style:italic">// 高度</span></span>
<span class="line"><span style="color:#61AFEF">        writeShortLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 颜色平面数</span></span>
<span class="line"><span style="color:#61AFEF">        writeShortLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">8</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 8位灰度</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 无压缩</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, IMAGE_SIZE </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> IMAGE_SIZE); </span><span style="color:#7F848E;font-style:italic">// 像素数据大小</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">2835</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 水平分辨率 (像素/米)</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">2835</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 垂直分辨率 (像素/米)</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">256</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 使用的颜色数</span></span>
<span class="line"><span style="color:#61AFEF">        writeIntLittleEndian</span><span style="color:#ABB2BF">(fos, </span><span style="color:#D19A66">256</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 重要的颜色数</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 写入像素数据</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> fos</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@throws</span><span style="color:#E5C07B;font-style:italic"> IOException</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> writePixelData</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75;font-style:italic"> fos</span><span style="color:#ABB2BF">)</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 灰度调色板 (256*4=1024字节)</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> i</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; i </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#D19A66"> 256</span><span style="color:#ABB2BF">; i++) {</span></span>
<span class="line"><span style="color:#E5C07B">            fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(i); </span><span style="color:#7F848E;font-style:italic">// B</span></span>
<span class="line"><span style="color:#E5C07B">            fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(i); </span><span style="color:#7F848E;font-style:italic">// G</span></span>
<span class="line"><span style="color:#E5C07B">            fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(i); </span><span style="color:#7F848E;font-style:italic">// R</span></span>
<span class="line"><span style="color:#E5C07B">            fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// A</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 随机生成黑点数 (1000-5000)</span></span>
<span class="line"><span style="color:#C678DD">        int</span><span style="color:#E06C75"> blackDots</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> random</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">nextInt</span><span style="color:#ABB2BF">(MAX_BLACK_DOTS </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1000</span><span style="color:#56B6C2"> +</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">+</span><span style="color:#D19A66"> 1000</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">        boolean</span><span style="color:#ABB2BF">[][] </span><span style="color:#E06C75">pixelArray</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#C678DD"> boolean</span><span style="color:#ABB2BF">[IMAGE_SIZE][IMAGE_SIZE];</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 随机放置黑点</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> i</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; i </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> blackDots; i++) {</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#E06C75"> x</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> random</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">nextInt</span><span style="color:#ABB2BF">(IMAGE_SIZE);</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#E06C75"> y</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> random</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">nextInt</span><span style="color:#ABB2BF">(IMAGE_SIZE);</span></span>
<span class="line"><span style="color:#ABB2BF">            pixelArray[x][y] </span><span style="color:#56B6C2">=</span><span style="color:#D19A66"> true</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 写入像素数据 (从下到上，从左到右)</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> y</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> IMAGE_SIZE </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">; y </span><span style="color:#56B6C2">>=</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; y--) {</span></span>
<span class="line"><span style="color:#C678DD">            for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> x</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; x </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> IMAGE_SIZE; x++) {</span></span>
<span class="line"><span style="color:#E5C07B">                fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(pixelArray[x][y] </span><span style="color:#C678DD">?</span><span style="color:#D19A66"> 0x00</span><span style="color:#C678DD"> :</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span><span style="color:#7F848E;font-style:italic">// 0x00 0xFF 对应调色版的编号</span></span>
<span class="line"><span style="color:#ABB2BF">            }</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 小端序写入一个int</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * &#x26; 0xFF 只留下最低的8个二进制位</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> fos</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> value</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@throws</span><span style="color:#E5C07B;font-style:italic"> IOException</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> writeIntLittleEndian</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75;font-style:italic"> fos</span><span style="color:#ABB2BF">, </span><span style="color:#C678DD">int</span><span style="color:#E06C75;font-style:italic"> value</span><span style="color:#ABB2BF">)</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(value </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">((value </span><span style="color:#56B6C2">>></span><span style="color:#D19A66"> 8</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">((value </span><span style="color:#56B6C2">>></span><span style="color:#D19A66"> 16</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">((value </span><span style="color:#56B6C2">>></span><span style="color:#D19A66"> 24</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 小端序写入一个short</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> fos</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> value</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@throws</span><span style="color:#E5C07B;font-style:italic"> IOException</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> writeShortLittleEndian</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">FileOutputStream</span><span style="color:#E06C75;font-style:italic"> fos</span><span style="color:#ABB2BF">, </span><span style="color:#C678DD">int</span><span style="color:#E06C75;font-style:italic"> value</span><span style="color:#ABB2BF">)</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">(value </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#E5C07B">        fos</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">write</span><span style="color:#ABB2BF">((value </span><span style="color:#56B6C2">>></span><span style="color:#D19A66"> 8</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div><div class="collapsed-lines"></div></div><div class="language-java line-numbers-mode has-collapsed-lines collapsed" data-highlighter="shiki" data-ext="java" style="--vp-collapsed-lines:15;background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#7F848E;font-style:italic">/**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @Author haomingze</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @Date 2025/5/12 21:38</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> * @description:</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic"> */</span></span>
<span class="line"><span style="color:#C678DD">public</span><span style="color:#C678DD"> class</span><span style="color:#E5C07B"> BmpProcessor</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> final</span><span style="color:#E5C07B"> Path</span><span style="color:#E06C75"> watchDir </span><span style="color:#56B6C2">=</span><span style="color:#E5C07B"> Paths</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"D:/"</span><span style="color:#ABB2BF">);</span><span style="color:#7F848E;font-style:italic">// 监听目录</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> final</span><span style="color:#E5C07B"> ExecutorService</span><span style="color:#E06C75"> threadPool </span><span style="color:#56B6C2">=</span><span style="color:#E5C07B"> Executors</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">newFixedThreadPool</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">20</span><span style="color:#ABB2BF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> startWatching</span><span style="color:#ABB2BF">()</span><span style="color:#C678DD"> throws</span><span style="color:#E5C07B"> IOException</span><span style="color:#ABB2BF">,</span><span style="color:#E5C07B"> InterruptedException</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">        WatchService</span><span style="color:#E06C75"> watchService</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> FileSystems</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getDefault</span><span style="color:#ABB2BF">().</span><span style="color:#61AFEF">newWatchService</span><span style="color:#ABB2BF">(); </span><span style="color:#7F848E;font-style:italic">// 创建一个监听器</span></span>
<span class="line"><span style="color:#E5C07B">        watchDir</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">register</span><span style="color:#ABB2BF">(watchService, ENTRY_CREATE); </span><span style="color:#7F848E;font-style:italic">// 给目录绑定监听器</span></span>
<span class="line"><span style="color:#E5C07B">        System</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">out</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">println</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"开始监听目录: "</span><span style="color:#56B6C2"> +</span><span style="color:#ABB2BF"> watchDir);</span></span>
<span class="line"><span style="color:#E5C07B">        WatchKey</span><span style="color:#E06C75"> key</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">        while</span><span style="color:#ABB2BF"> ((key </span><span style="color:#56B6C2">=</span><span style="color:#E5C07B"> watchService</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">take</span><span style="color:#ABB2BF">()) </span><span style="color:#56B6C2">!=</span><span style="color:#D19A66"> null</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"><span style="color:#C678DD">            for</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">WatchEvent</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#C678DD">?</span><span style="color:#ABB2BF">> </span><span style="color:#E06C75">event</span><span style="color:#C678DD"> :</span><span style="color:#E5C07B"> key</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">pollEvents</span><span style="color:#ABB2BF">()) {</span></span>
<span class="line"><span style="color:#C678DD">                if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">kind</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">==</span><span style="color:#ABB2BF"> ENTRY_CREATE) {</span></span>
<span class="line"><span style="color:#E5C07B">                    Path</span><span style="color:#E06C75"> filePath</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> watchDir</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">resolve</span><span style="color:#ABB2BF">((Path) </span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">context</span><span style="color:#ABB2BF">());</span></span>
<span class="line"><span style="color:#E5C07B">                    threadPool</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">execute</span><span style="color:#ABB2BF">(()</span><span style="color:#C678DD">-></span><span style="color:#61AFEF"> processFile</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">filePath</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">toFile</span><span style="color:#ABB2BF">()));</span></span>
<span class="line"><span style="color:#ABB2BF">                }</span></span>
<span class="line"><span style="color:#ABB2BF">            }</span></span>
<span class="line"><span style="color:#E5C07B">            key</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">reset</span><span style="color:#ABB2BF">();</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> void</span><span style="color:#61AFEF"> processFile</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">File</span><span style="color:#E06C75;font-style:italic"> file</span><span style="color:#ABB2BF">)</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#E5C07B">        System</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">err</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">println</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"监听到新增文件:"</span><span style="color:#56B6C2">+</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getAbsolutePath</span><span style="color:#ABB2BF">());</span></span>
<span class="line"><span style="color:#C678DD">        synchronized</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">BmpGenerator</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">lockMap</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getAbsolutePath</span><span style="color:#ABB2BF">())){</span></span>
<span class="line"><span style="color:#E5C07B">            System</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">err</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">println</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"新增BMP黑点围起来的凸包面积大小为:"</span><span style="color:#56B6C2"> +</span><span style="color:#61AFEF"> calculateBlackPolygonArea</span><span style="color:#ABB2BF">(file));</span></span>
<span class="line"><span style="color:#E5C07B">            System</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">err</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">println</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getAbsolutePath</span><span style="color:#ABB2BF">()</span><span style="color:#56B6C2">+</span><span style="color:#98C379">"是否删除成功:"</span><span style="color:#56B6C2">+</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">delete</span><span style="color:#ABB2BF">());</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 计算多边形面记</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> file</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@return</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> double</span><span style="color:#61AFEF"> calculateBlackPolygonArea</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">File</span><span style="color:#E06C75;font-style:italic"> file</span><span style="color:#ABB2BF">){</span></span>
<span class="line"><span style="color:#C678DD">        try</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">FileInputStream</span><span style="color:#E06C75"> fis</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> FileInputStream</span><span style="color:#ABB2BF">(file)) {</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 跳过文件头和信息头</span></span>
<span class="line"><span style="color:#C678DD">            byte</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75">header</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#C678DD"> byte</span><span style="color:#ABB2BF">[</span><span style="color:#D19A66">54</span><span style="color:#ABB2BF">];</span></span>
<span class="line"><span style="color:#C678DD">            if</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">fis</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">read</span><span style="color:#ABB2BF">(header) </span><span style="color:#56B6C2">!=</span><span style="color:#D19A66"> 54</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">throw</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> IOException</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"BMP文件头不完整"</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 读取小端序宽度和高度</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#E06C75"> width</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">21</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 24</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">20</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 16</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">19</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 8</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> (header[</span><span style="color:#D19A66">18</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#E06C75"> height</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">25</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 24</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">24</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 16</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> ((header[</span><span style="color:#D19A66">23</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">&#x3C;&#x3C;</span><span style="color:#D19A66"> 8</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">|</span><span style="color:#ABB2BF"> (header[</span><span style="color:#D19A66">22</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">&#x26;</span><span style="color:#D19A66"> 0xFF</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 跳过调色板</span></span>
<span class="line"><span style="color:#C678DD">            byte</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75">palette</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#C678DD"> byte</span><span style="color:#ABB2BF">[</span><span style="color:#D19A66">1024</span><span style="color:#ABB2BF">];</span></span>
<span class="line"><span style="color:#C678DD">            if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">fis</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">read</span><span style="color:#ABB2BF">(palette) </span><span style="color:#56B6C2">!=</span><span style="color:#D19A66"> 1024</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">throw</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> IOException</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"BMP调色板不完整"</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 计算每行字节数</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#E06C75"> rowSize</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> (width </span><span style="color:#56B6C2">+</span><span style="color:#D19A66"> 3</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">/</span><span style="color:#D19A66"> 4</span><span style="color:#56B6C2"> *</span><span style="color:#D19A66"> 4</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">            byte</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75">pixelData</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#C678DD"> byte</span><span style="color:#ABB2BF">[rowSize </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> height];</span></span>
<span class="line"><span style="color:#C678DD">            if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">fis</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">read</span><span style="color:#ABB2BF">(pixelData) </span><span style="color:#56B6C2">!=</span><span style="color:#E5C07B"> pixelData</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">length</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">throw</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> IOException</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">"BMP像素数据不完整"</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 提取黑点像素</span></span>
<span class="line"><span style="color:#E5C07B">            List</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[]> </span><span style="color:#E06C75">blackPixels</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#E5C07B"> ArrayList</span><span style="color:#ABB2BF">&#x3C;>();</span></span>
<span class="line"><span style="color:#C678DD">            for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> y</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; y </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> height; y++) {</span></span>
<span class="line"><span style="color:#C678DD">                for</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> x</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; x </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> width; x++) {</span></span>
<span class="line"><span style="color:#C678DD">                    int</span><span style="color:#E06C75"> pixelIndex</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> (height </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> y </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> rowSize </span><span style="color:#56B6C2">+</span><span style="color:#ABB2BF"> x;</span></span>
<span class="line"><span style="color:#C678DD">                    if</span><span style="color:#ABB2BF"> (pixelData[pixelIndex] </span><span style="color:#56B6C2">==</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">) </span><span style="color:#E5C07B">blackPixels</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">add</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">new</span><span style="color:#C678DD"> int</span><span style="color:#ABB2BF">[]{x, y});</span></span>
<span class="line"><span style="color:#ABB2BF">                }</span></span>
<span class="line"><span style="color:#ABB2BF">            }</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">            // 计算面积</span></span>
<span class="line"><span style="color:#C678DD">            return</span><span style="color:#61AFEF"> calcalateArea</span><span style="color:#ABB2BF">(blackPixels);</span></span>
<span class="line"><span style="color:#ABB2BF">        } </span><span style="color:#C678DD">catch</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">IOException</span><span style="color:#E06C75;font-style:italic"> e</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"><span style="color:#E5C07B">            System</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">err</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">println</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">file</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">getAbsolutePath</span><span style="color:#ABB2BF">()</span><span style="color:#56B6C2">+</span><span style="color:#98C379">"文件发生异常"</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#C678DD">            throw</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> RuntimeException</span><span style="color:#ABB2BF">(e);</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 通过多边形点坐标求多边形面积</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 算法思想</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 将所有点按x排序，x相同按照y排序</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 从左到右扫描点，动态计算凸包的凹凸性</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 从右到左同理，合并上下半部分，形成凸包</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 根据凸包计算面积</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@return</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    public</span><span style="color:#C678DD"> double</span><span style="color:#61AFEF"> calcalateArea</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">List</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[]> </span><span style="color:#E06C75;font-style:italic">points</span><span style="color:#ABB2BF">){</span></span>
<span class="line"><span style="color:#E5C07B">        points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">sort</span><span style="color:#ABB2BF">((a,b)</span><span style="color:#C678DD">-></span><span style="color:#ABB2BF"> a[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">==</span><span style="color:#ABB2BF"> b[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#C678DD">?</span><span style="color:#ABB2BF"> a[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> b[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">] </span><span style="color:#C678DD">:</span><span style="color:#ABB2BF"> a[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> b[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">]); </span><span style="color:#7F848E;font-style:italic">// 排序</span></span>
<span class="line"><span style="color:#C678DD">        int</span><span style="color:#E06C75"> n</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">(); </span><span style="color:#7F848E;font-style:italic">// 获取点的长度</span></span>
<span class="line"><span style="color:#E5C07B">        List</span><span style="color:#ABB2BF">&#x3C;</span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[]> </span><span style="color:#E06C75">hull</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#E5C07B"> ArrayList</span><span style="color:#ABB2BF">&#x3C;>(</span><span style="color:#D19A66">2</span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF">n);</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 求下半部分</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> i</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; i </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> n; i++) {</span></span>
<span class="line"><span style="color:#C678DD">            while</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">>=</span><span style="color:#D19A66"> 2</span><span style="color:#56B6C2"> &#x26;&#x26;</span><span style="color:#61AFEF"> cross</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">()</span><span style="color:#56B6C2">-</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">),</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">()</span><span style="color:#56B6C2">-</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">),</span><span style="color:#E5C07B">points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(i)) </span><span style="color:#56B6C2">&#x3C;=</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">) </span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">remove</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">()</span><span style="color:#56B6C2">-</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">); </span><span style="color:#7F848E;font-style:italic">// 此时凹凸性不满足,退出点</span></span>
<span class="line"><span style="color:#E5C07B">            hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">add</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(i));</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 求上半部分</span></span>
<span class="line"><span style="color:#C678DD">        int</span><span style="color:#E06C75"> t</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">+</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> i</span><span style="color:#56B6C2"> =</span><span style="color:#ABB2BF"> n</span><span style="color:#56B6C2">-</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">; i </span><span style="color:#56B6C2">>=</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; i--){</span></span>
<span class="line"><span style="color:#C678DD">            while</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">>=</span><span style="color:#ABB2BF"> t </span><span style="color:#56B6C2">&#x26;&#x26;</span><span style="color:#61AFEF"> cross</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 2</span><span style="color:#ABB2BF">), </span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">), </span><span style="color:#E5C07B">points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(i)) </span><span style="color:#56B6C2">&#x3C;=</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">) </span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">remove</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">);</span></span>
<span class="line"><span style="color:#E5C07B">            hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">add</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">points</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(i));</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 移除最后一个点，它与第一个点重复</span></span>
<span class="line"><span style="color:#E5C07B">        hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">remove</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">() </span><span style="color:#56B6C2">-</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">        // 计算面积</span></span>
<span class="line"><span style="color:#C678DD">        double</span><span style="color:#E06C75"> area</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0.0</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#ABB2BF">        n </span><span style="color:#56B6C2">=</span><span style="color:#E5C07B"> hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">size</span><span style="color:#ABB2BF">();</span></span>
<span class="line"><span style="color:#C678DD">        for</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">int</span><span style="color:#E06C75"> i</span><span style="color:#56B6C2"> =</span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">; i </span><span style="color:#56B6C2">&#x3C;</span><span style="color:#ABB2BF"> n; i++){</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75">p1</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">(i);</span></span>
<span class="line"><span style="color:#C678DD">            int</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75">p2</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> hull</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">get</span><span style="color:#ABB2BF">((i </span><span style="color:#56B6C2">+</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">) </span><span style="color:#56B6C2">%</span><span style="color:#ABB2BF"> n); </span><span style="color:#7F848E;font-style:italic">// 最后一个是第一个点所以得取余</span></span>
<span class="line"><span style="color:#ABB2BF">            area </span><span style="color:#56B6C2">+=</span><span style="color:#ABB2BF"> (p1[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> p2[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> p2[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> p1[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">]); </span><span style="color:#7F848E;font-style:italic">// 向量计算面积</span></span>
<span class="line"><span style="color:#ABB2BF">        }</span></span>
<span class="line"><span style="color:#C678DD">        return</span><span style="color:#ABB2BF"> area;</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">    /**</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * 计算新加入的点，在已加入的点的内测还是外侧，返回正值保留，返回负值</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> o</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> a</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@param</span><span style="color:#E06C75;font-style:italic"> b</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     * </span><span style="color:#C678DD;font-style:italic">@return</span></span>
<span class="line"><span style="color:#7F848E;font-style:italic">     */</span></span>
<span class="line"><span style="color:#C678DD">    private</span><span style="color:#C678DD"> int</span><span style="color:#61AFEF"> cross</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75;font-style:italic">o</span><span style="color:#ABB2BF">, </span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75;font-style:italic">a</span><span style="color:#ABB2BF">, </span><span style="color:#C678DD">int</span><span style="color:#ABB2BF">[] </span><span style="color:#E06C75;font-style:italic">b</span><span style="color:#ABB2BF">)</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#C678DD">        return</span><span style="color:#ABB2BF"> (a[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> o[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">]) </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> (b[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> o[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">]) </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> (a[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> o[</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">]) </span><span style="color:#56B6C2">*</span><span style="color:#ABB2BF"> (b[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">] </span><span style="color:#56B6C2">-</span><span style="color:#ABB2BF"> o[</span><span style="color:#D19A66">0</span><span style="color:#ABB2BF">]);</span></span>
<span class="line"><span style="color:#ABB2BF">    }</span></span>
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div><div class="collapsed-lines"></div></div><blockquote>
<p>参考：</p>
<p><a href="https://baike.baidu.com/item/BMP%E6%A0%BC%E5%BC%8F/3427000" target="_blank" rel="noopener noreferrer">BMP格式_百度百科</a></p>
<p><a href="https://blog.csdn.net/lemonxiaoxiao/article/details/108619552" target="_blank" rel="noopener noreferrer">凸包（Convex Hull）问题算法详解_凸包算法 chen-CSDN博客</a></p>
<p><a href="https://www.zhihu.com/question/22298352/answer/1071892762" target="_blank" rel="noopener noreferrer">如何通俗易懂地解释卷积？ - 知乎</a></p>
<p><a href="https://www.zhihu.com/question/28623194/answer/1441668140" target="_blank" rel="noopener noreferrer">如何理解矩阵相乘的几何意义或现实意义？ - 知乎</a></p>
</blockquote>
</div></template>


